package com.agileai.bpm.common;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import com.agileai.bpm.domain.define.Activity;
import com.agileai.bpm.domain.define.ProcessVariable;
import com.agileai.bpm.domain.define.Transition;
import com.agileai.bpm.interceptor.BaseInterceptor;
import com.agileai.bpm.model.ActivitiesDocument.Activities;
import com.agileai.bpm.model.AuditActivityType;
import com.agileai.bpm.model.DBOperaterType;
import com.agileai.bpm.model.DataFieldsDocument.DataFields;
import com.agileai.bpm.model.EndActivityType;
import com.agileai.bpm.model.FlowLauncherType;
import com.agileai.bpm.model.ForkActivityType;
import com.agileai.bpm.model.InterceptorModelDocument.InterceptorModel;
import com.agileai.bpm.model.InvokeActivityType;
import com.agileai.bpm.model.JoinActivityType;
import com.agileai.bpm.model.ManualActivityType;
import com.agileai.bpm.model.ProcessDefineDocument.ProcessDefine;
import com.agileai.bpm.model.RestInvokerType;
import com.agileai.bpm.model.StartActivityType;
import com.agileai.bpm.model.TransitionType;
import com.agileai.bpm.model.TransitionsDocument.Transitions;
import com.agileai.bpm.model.VariableType;
import com.agileai.bpm.model.WatchActivityType;
import com.agileai.bpm.model.WatchInvokerType;

public class ProcessDefineUtil {
	
	public static Activity findActivityById(List<Activity> activities,String id){
		Activity result = null;
		for (int i=0;i < activities.size();i++){
			Activity activity = activities.get(i);
			if (id.equals(activity.getId())){
				result = activity;
				break;
			}
		}
		return result;
	}
	
	public static Transition findTransition(List<Transition> transitions,String code){
		Transition result = null;
		for (int i=0;i < transitions.size();i++){
			Transition transition = transitions.get(i);
			if (code.equals(transition.getCode())){
				result = transition;
				break;
			}
		}
		return result;
	}
	
	public static ProcessVariable findProcessVariable(List<ProcessVariable> processVariables,String code){
		ProcessVariable result = null;
		for (int i=0;i < processVariables.size();i++){
			ProcessVariable processVariable = processVariables.get(i);
			if (code.equals(processVariable.getCode())){
				result = processVariable;
				break;
			}
		}
		return result;
	}	
	
	public static TransitionType getTransitionType(ProcessDefine processDefine,String transitionId){
		TransitionType result = null;
		Transitions transitions = processDefine.getTransitions();
		if (transitions != null){
			TransitionType[] transitionTypes = transitions.getTransitionArray();
			for (int i=0;i < transitionTypes.length;i++){
				TransitionType transitionType = transitionTypes[i];
				String id = transitionType.getId();
				if (transitionId.equals(id)){
					result = transitionType;
					break;
				}
			}
		}
		return result;
	}
	
	public static void setTransitionId(ProcessDefine processDefine,String transCode,String id,HashMap<String,String> mappings){
		Transitions transitions = processDefine.getTransitions();
		if (transitions != null){
			TransitionType[] transitionTypes = transitions.getTransitionArray();
			for (int i=0;i < transitionTypes.length;i++){
				TransitionType transitionType = transitionTypes[i];
				String cod = transitionType.getCode();
				if (transCode.equals(cod)){
					transitionType.setId(id);
					String oldFromId = transitionType.getFrom();
					String oldToId = transitionType.getTo();
					String newFromId = mappings.get(oldFromId);
					String newToId = mappings.get(oldToId);
					transitionType.setFrom(newFromId);
					transitionType.setTo(newToId);
				}
			}
		}
	}
	
	public static List<TransitionType> getOutTransitionList(ProcessDefine processDefine,String activityId){
		List<TransitionType> result = new ArrayList<TransitionType>();
		Transitions transitions = processDefine.getTransitions();
		if (transitions != null){
			TransitionType[] transitionTypes = transitions.getTransitionArray();
			for (int i=0;i < transitionTypes.length;i++){
				TransitionType transitionType = transitionTypes[i];
				String fromId = transitionType.getFrom();
				if (activityId.equals(fromId)){
					result.add(transitionType);
				}
			}
		}
		return result;
	}
	
	public static boolean isStartActivity(ProcessDefine processDefine,String activityId){
		boolean result = false;
		Activities activities = processDefine.getActivities();
		StartActivityType startActivityType = activities.getStartActivity();
		if (startActivityType != null && activityId != null && activityId.equals(startActivityType.getId())){
			result = true;
		}
		return result;
	}
	
	public static boolean isEndActivity(ProcessDefine processDefine,String activityId){
		boolean result = false;
		Activities activities = processDefine.getActivities();
		EndActivityType endActivityType = activities.getEndActivity();
		if (endActivityType != null && activityId != null && activityId.equals(endActivityType.getId())){
			result = true;
		}
		return result;
	}
	
	public static boolean isPointToEndActivity(ProcessDefine processDefine,String activityId){
		boolean result = false;
		List<TransitionType> transList = ProcessDefineUtil.getOutTransitionList(processDefine, activityId);
		if (transList != null){
			for (int i=0;i < transList.size();i++){
				TransitionType transitionType = transList.get(i);
				String tempToId = transitionType.getTo();
				if (ProcessDefineUtil.isEndActivity(processDefine, tempToId)){
					result = true;
					break;
				}
			}
		}
		return result;
	}
	
	public static List<TransitionType> getInTransitionList(ProcessDefine processDefine,String activityId){
		List<TransitionType> result = new ArrayList<TransitionType>();
		Transitions transitions = processDefine.getTransitions();
		if (transitions != null){
			TransitionType[] transitionTypes = transitions.getTransitionArray();
			for (int i=0;i < transitionTypes.length;i++){
				TransitionType transitionType = transitionTypes[i];
				String toId = transitionType.getTo();
				if (activityId.equals(toId)){
					result.add(transitionType);
				}
			}
		}
		return result;
	}
	
	public static void setActivityId(ProcessDefine processDefine,String activityCode,String id,HashMap<String,String> mappings){
		Activities activities = processDefine.getActivities();
		
		StartActivityType startActivityType = activities.getStartActivity();
		if (startActivityType != null && activityCode.equals(startActivityType.getCode())){
			mappings.put(startActivityType.getId(), id);
			startActivityType.setId(id);
		}
		
		EndActivityType endActivityType = activities.getEndActivity();
		if (endActivityType != null && activityCode.equals(endActivityType.getCode())){
			mappings.put(endActivityType.getId(), id); 
			endActivityType.setId(id);
		}
		
		ManualActivityType[] manualActivityTypes = activities.getManualActivityArray();
		for (int i=0;i < manualActivityTypes.length;i++){
			ManualActivityType manualActivityType = manualActivityTypes[i];
			if (activityCode.equals(manualActivityType.getCode())){
				mappings.put(manualActivityType.getId(), id);
				manualActivityType.setId(id);
			}
		}
		
		AuditActivityType[] auditActivityTypes = activities.getAuditActivityArray();
		for (int i=0;i < auditActivityTypes.length;i++){
			AuditActivityType auditActivityType = auditActivityTypes[i];
			if (activityCode.equals(auditActivityType.getCode())){
				mappings.put(auditActivityType.getId(), id);
				auditActivityType.setId(id);
			}
		}
		
		ForkActivityType[] forkActivityTypes = activities.getForkActivityArray();
		for (int i=0;i < forkActivityTypes.length;i++){
			ForkActivityType forkActivityType = forkActivityTypes[i];
			if (activityCode.equals(forkActivityType.getCode())){
				mappings.put(forkActivityType.getId(), id);
				forkActivityType.setId(id);
			}
		}
		
		JoinActivityType[] joinActivityTypes = activities.getJoinActivityArray();
		for (int i=0;i < joinActivityTypes.length;i++){
			JoinActivityType joinActivityType = joinActivityTypes[i];
			if (activityCode.equals(joinActivityType.getCode())){
				mappings.put(joinActivityType.getId(), id);
				joinActivityType.setId(id);
			}
		}
		
		InvokeActivityType[] invokeActivityTypes = activities.getInvokeActivityArray();
		for (int i=0;i < invokeActivityTypes.length;i++){
			InvokeActivityType invokeActivityType = invokeActivityTypes[i];
			if (activityCode.equals(invokeActivityType.getCode())){
				mappings.put(invokeActivityType.getId(), id);
				invokeActivityType.setId(id);
			}
		}
		
		WatchActivityType[] watchActivityTypes = activities.getWatchActivityArray();
		for (int i=0;i < watchActivityTypes.length;i++){
			WatchActivityType watchActivityType = watchActivityTypes[i];
			if (activityCode.equals(watchActivityType.getCode())){
				mappings.put(watchActivityType.getId(), id);
				watchActivityType.setId(id);
			}
		}		
	}
	
	public static String getActivityName(ProcessDefine processDefine,String activityId){
		String result = "";
		Activities activities = processDefine.getActivities();
		
		StartActivityType startActivityType = activities.getStartActivity();
		if (startActivityType != null && activityId.equals(startActivityType.getId())){
			return startActivityType.getName();
		}
		
		EndActivityType endActivityType = activities.getEndActivity();
		if (endActivityType != null && activityId.equals(endActivityType.getId())){
			 return  endActivityType.getName();
		}
		
		ManualActivityType[] manualActivityTypes = activities.getManualActivityArray();
		for (int i=0;i < manualActivityTypes.length;i++){
			ManualActivityType manualActivityType = manualActivityTypes[i];
			if (activityId.equals(manualActivityType.getId())){
				return manualActivityType.getName();
			}
		}
		
		AuditActivityType[] auditActivityTypes = activities.getAuditActivityArray();
		for (int i=0;i < auditActivityTypes.length;i++){
			AuditActivityType auditActivityType = auditActivityTypes[i];
			if (activityId.equals(auditActivityType.getId())){
				return auditActivityType.getName();
			}
		}		
		
		ForkActivityType[] forkActivityTypes = activities.getForkActivityArray();
		for (int i=0;i < forkActivityTypes.length;i++){
			ForkActivityType forkActivityType = forkActivityTypes[i];
			if (activityId.equals(forkActivityType.getId())){
				return forkActivityType.getName();
			}
		}
		
		JoinActivityType[] joinActivityTypes = activities.getJoinActivityArray();
		for (int i=0;i < joinActivityTypes.length;i++){
			JoinActivityType joinActivityType = joinActivityTypes[i];
			if (activityId.equals(joinActivityType.getId())){
				return joinActivityType.getName();
			}
		}	
		
		WatchActivityType[] watchActivityTypes = activities.getWatchActivityArray();
		for (int i=0;i < watchActivityTypes.length;i++){
			WatchActivityType watchActivityType = watchActivityTypes[i];
			if (activityId.equals(watchActivityType.getId())){
				return watchActivityType.getName();
			}
		}	
		
		InvokeActivityType[] invokeActivityTypes = activities.getInvokeActivityArray();
		for (int i=0;i < invokeActivityTypes.length;i++){
			InvokeActivityType invokeActivityType = invokeActivityTypes[i];
			if (activityId.equals(invokeActivityType.getId())){
				return invokeActivityType.getName();
			}
		}	
		
		return result;
	}
	
	public static String getActivityCode(ProcessDefine processDefine,String activityId){
		String result = "";
		Activities activities = processDefine.getActivities();
		
		StartActivityType startActivityType = activities.getStartActivity();
		if (startActivityType != null && activityId.equals(startActivityType.getId())){
			return startActivityType.getCode();
		}
		
		EndActivityType endActivityType = activities.getEndActivity();
		if (endActivityType != null && activityId.equals(endActivityType.getId())){
			 return  endActivityType.getCode();
		}
		
		ManualActivityType[] manualActivityTypes = activities.getManualActivityArray();
		for (int i=0;i < manualActivityTypes.length;i++){
			ManualActivityType manualActivityType = manualActivityTypes[i];
			if (activityId.equals(manualActivityType.getId())){
				return manualActivityType.getCode();
			}
		}
		
		AuditActivityType[] auditActivityTypes = activities.getAuditActivityArray();
		for (int i=0;i < auditActivityTypes.length;i++){
			AuditActivityType auditActivityType = auditActivityTypes[i];
			if (activityId.equals(auditActivityType.getId())){
				return auditActivityType.getCode();
			}
		}		

		ForkActivityType[] forkActivityTypes = activities.getForkActivityArray();
		for (int i=0;i < forkActivityTypes.length;i++){
			ForkActivityType forkActivityType = forkActivityTypes[i];
			if (activityId.equals(forkActivityType.getId())){
				return forkActivityType.getCode();
			}
		}
		
		JoinActivityType[] joinActivityTypes = activities.getJoinActivityArray();
		for (int i=0;i < joinActivityTypes.length;i++){
			JoinActivityType joinActivityType = joinActivityTypes[i];
			if (activityId.equals(joinActivityType.getId())){
				return joinActivityType.getCode();
			}
		}	
		
		WatchActivityType[] watchActivityTypes = activities.getWatchActivityArray();
		for (int i=0;i < watchActivityTypes.length;i++){
			WatchActivityType watchActivityType = watchActivityTypes[i];
			if (activityId.equals(watchActivityType.getId())){
				return watchActivityType.getCode();
			}
		}	
		
		InvokeActivityType[] invokeActivityTypes = activities.getInvokeActivityArray();
		for (int i=0;i < invokeActivityTypes.length;i++){
			InvokeActivityType invokeActivityType = invokeActivityTypes[i];
			if (activityId.equals(invokeActivityType.getId())){
				return invokeActivityType.getCode();
			}
		}			
		return result;
	}
	
	public static ManualActivityType getManualActivityType(Activities activities,String activityId){
		ManualActivityType[] manualActivityTypes = activities.getManualActivityArray();
		for (int i=0;i < manualActivityTypes.length;i++){
			ManualActivityType manualActivityType = manualActivityTypes[i];
			if (activityId.equals(manualActivityType.getId())){
				return manualActivityType;
			}
		}
		return null;
	}
	
	public static AuditActivityType getAuditActivityType(Activities activities,String activityId){
		AuditActivityType[] auditActivityTypes = activities.getAuditActivityArray();
		for (int i=0;i < auditActivityTypes.length;i++){
			AuditActivityType manualActivityType = auditActivityTypes[i];
			if (activityId.equals(manualActivityType.getId())){
				return manualActivityType;
			}
		}
		return null;
	}
	
	public static InvokeActivityType getInvokeActivityType(Activities activities,String activityId){
		InvokeActivityType[] invokeActivityTypes = activities.getInvokeActivityArray();
		for (int i=0;i < invokeActivityTypes.length;i++){
			InvokeActivityType invokeActivityType = invokeActivityTypes[i];
			if (activityId.equals(invokeActivityType.getId())){
				return invokeActivityType;
			}
		}
		return null;
	}	
	
	public static InterceptorModel getInterceptorModel(ProcessDefine processDefine
			,String position,String activityId,String interceptorId){
		InterceptorModel result = null;
		Activities activities = processDefine.getActivities();
		
		ManualActivityType manualActivityType = getManualActivityType(activities, activityId);
		if (manualActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = manualActivityType.getInInterceptors().getInterceptorModelArray();	
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = manualActivityType.getOutInterceptors().getInterceptorModelArray();
			}
			for (int i=0;i < interceptorModels.length;i++){
				InterceptorModel temp = interceptorModels[i];
				if (temp.getId().equals(interceptorId)){
					result = temp;
					break;
				}
			}
		}
		
		AuditActivityType auditActivityType = getAuditActivityType(activities, activityId);
		if (auditActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = auditActivityType.getInInterceptors().getInterceptorModelArray();	
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = auditActivityType.getOutInterceptors().getInterceptorModelArray();
			}
			for (int i=0;i < interceptorModels.length;i++){
				InterceptorModel temp = interceptorModels[i];
				if (temp.getId().equals(interceptorId)){
					result = temp;
					break;
				}
			}
		}
		
		InvokeActivityType invokeActivityType = getInvokeActivityType(activities, activityId);
		if (invokeActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = invokeActivityType.getInInterceptors().getInterceptorModelArray();	
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = invokeActivityType.getOutInterceptors().getInterceptorModelArray();
			}
			for (int i=0;i < interceptorModels.length;i++){
				InterceptorModel temp = interceptorModels[i];
				if (temp.getId().equals(interceptorId)){
					result = temp;
					break;
				}
			}
		}
		
		return result;
	}
	
	public static void deleteInterceptorModel(ProcessDefine processDefine
			,String position,String activityId,String interceptorId){
		int matchedIndex = 0;
		Activities activities = processDefine.getActivities();
		
		ManualActivityType manualActivityType = getManualActivityType(activities, activityId);
		if (manualActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = manualActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				manualActivityType.getInInterceptors().removeInterceptorModel(matchedIndex);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = manualActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				manualActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex);
			}
		}
		
		AuditActivityType auditActivityType = getAuditActivityType(activities, activityId);
		if (auditActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = auditActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				auditActivityType.getInInterceptors().removeInterceptorModel(matchedIndex);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = auditActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				auditActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex);
			}
		}
		
		InvokeActivityType invokeActivityType = getInvokeActivityType(activities, activityId);
		if (invokeActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = invokeActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				invokeActivityType.getInInterceptors().removeInterceptorModel(matchedIndex);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = invokeActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				invokeActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex);
			}
		}		
	}
	
	private static void copyInterceptorModel(InterceptorModel src,InterceptorModel target){
		if (src.isSetDBOperater()){
			DBOperaterType dbOperaterType = target.addNewDBOperater();
			DBOperaterType srcDbOperaterType = src.getDBOperater();
			dbOperaterType.setDataSource(srcDbOperaterType.getDataSource());
			dbOperaterType.setUpdateSQL(srcDbOperaterType.getUpdateSQL());
		}
		else if (src.isSetRestInvoker()){
			RestInvokerType invokerType = target.addNewRestInvoker();
			RestInvokerType srcInvokerType = src.getRestInvoker();
			invokerType.setHttpURL(srcInvokerType.getHttpURL());
			invokerType.setRequestJson(srcInvokerType.getRequestJson());
		}
		else if (src.isSetFlowLauncher()){
			FlowLauncherType flowLauncherType = target.addNewFlowLauncher();
			FlowLauncherType srcLauncherType = src.getFlowLauncher();
			flowLauncherType.setBizRecordId(srcLauncherType.getBizRecordId());	
			flowLauncherType.setProcessCode(srcLauncherType.getProcessCode());
			flowLauncherType.setProcessTitle(srcLauncherType.getProcessTitle());
			flowLauncherType.setSkipFirstManual(srcLauncherType.getSkipFirstManual());
			if (srcLauncherType.getBizAttributeArray() != null){
				flowLauncherType.setBizAttributeArray(srcLauncherType.getBizAttributeArray());
			}
		}
		else if (src.isSetWatchInvoker()){
			WatchInvokerType watchInvokerType = target.addNewWatchInvoker();
			WatchInvokerType srcWatchInvokerType = src.getWatchInvoker();
			watchInvokerType.setBizRecordId(srcWatchInvokerType.getBizRecordId());
			watchInvokerType.setProcessCode(srcWatchInvokerType.getProcessCode());
			watchInvokerType.setActivityCode(srcWatchInvokerType.getActivityCode());
			
			if (srcWatchInvokerType.getBizAttributeArray() != null){
				watchInvokerType.setBizAttributeArray(srcWatchInvokerType.getBizAttributeArray());
			}
		}
		
		target.setId(src.getId());
		target.setName(src.getName());
		if (src.getVarExpression() != null){
			target.setVarExpression(src.getVarExpression());			
		}
		target.setSynchronous(src.getSynchronous());
		if (src.getSynchronous()){
			if (src.getVariableCode() != null){
				target.setVariableCode(src.getVariableCode());				
			}
		}
	}
	
	public static void moveupInterceptorModel(ProcessDefine processDefine
			,String position,String activityId,String interceptorId) throws Exception{
		int matchedIndex = 0;
		Activities activities = processDefine.getActivities();
		
		ManualActivityType manualActivityType = getManualActivityType(activities, activityId);
		if (manualActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = manualActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = manualActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = manualActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex-1);
				copyInterceptorModel(currentInterceptorModel,newModel);
				manualActivityType.getInInterceptors().removeInterceptorModel(matchedIndex+1);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = manualActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = manualActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = manualActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex-1);
				copyInterceptorModel(currentInterceptorModel,newModel);
				manualActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex+1);
			}
		}
		
		AuditActivityType auditActivityType = getAuditActivityType(activities, activityId);
		if (auditActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = auditActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = auditActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = auditActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex-1);
				copyInterceptorModel(currentInterceptorModel,newModel);
				auditActivityType.getInInterceptors().removeInterceptorModel(matchedIndex+1);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = auditActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = auditActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = auditActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex-1);
				copyInterceptorModel(currentInterceptorModel,newModel);
				auditActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex+1);
			}
		}	
		
		InvokeActivityType invokeActivityType = getInvokeActivityType(activities, activityId);
		if (invokeActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = invokeActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = invokeActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = invokeActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex-1);
				copyInterceptorModel(currentInterceptorModel,newModel);
				invokeActivityType.getInInterceptors().removeInterceptorModel(matchedIndex+1);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = invokeActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = invokeActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = invokeActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex-1);
				copyInterceptorModel(currentInterceptorModel,newModel);
				invokeActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex+1);
			}
		}
	}
	
	public static void movedownInterceptorModel(ProcessDefine processDefine
			,String position,String activityId,String interceptorId) throws Exception{
		int matchedIndex = 0;
		Activities activities = processDefine.getActivities();
		
		ManualActivityType manualActivityType = getManualActivityType(activities, activityId);
		if (manualActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = manualActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = manualActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = manualActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex+2);
				copyInterceptorModel(currentInterceptorModel,newModel);
				manualActivityType.getInInterceptors().removeInterceptorModel(matchedIndex);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = manualActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = manualActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = manualActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex+2);
				copyInterceptorModel(currentInterceptorModel,newModel);
				manualActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex);
			}
		}
		
		AuditActivityType auditActivityType = getAuditActivityType(activities, activityId);
		if (auditActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = auditActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = auditActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = auditActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex+2);
				copyInterceptorModel(currentInterceptorModel,newModel);
				auditActivityType.getInInterceptors().removeInterceptorModel(matchedIndex);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = auditActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = auditActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = auditActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex+2);
				copyInterceptorModel(currentInterceptorModel,newModel);
				auditActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex);
			}
		}		
		
		InvokeActivityType invokeActivityType = getInvokeActivityType(activities, activityId);
		if (invokeActivityType != null){
			InterceptorModel[] interceptorModels = null;
			if (BaseInterceptor.Position.in.equals(position)){
				interceptorModels = invokeActivityType.getInInterceptors().getInterceptorModelArray();	
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = invokeActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = invokeActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex+2);
				copyInterceptorModel(currentInterceptorModel,newModel);
				invokeActivityType.getInInterceptors().removeInterceptorModel(matchedIndex);
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				interceptorModels = invokeActivityType.getOutInterceptors().getInterceptorModelArray();
				matchedIndex = getMatchedIndex(interceptorModels, interceptorId);
				InterceptorModel currentInterceptorModel = invokeActivityType.getInInterceptors().getInterceptorModelArray(matchedIndex);
				InterceptorModel newModel = invokeActivityType.getInInterceptors().insertNewInterceptorModel(matchedIndex+2);
				copyInterceptorModel(currentInterceptorModel,newModel);
				invokeActivityType.getOutInterceptors().removeInterceptorModel(matchedIndex);
			}
		}	
	}	
	
	
	private static int getMatchedIndex(InterceptorModel[] interceptorModels,String interceptorId){
		for (int i=0;i < interceptorModels.length;i++){
			InterceptorModel temp = interceptorModels[i];
			if (temp.getId().equals(interceptorId)){
				return i;
			}
		}
		return 0;
	}
	
	public static VariableType createProcessVariableType(ProcessDefine processDefine){
		VariableType result = null;
		DataFields dataFields = processDefine.getDataFields();
		if (dataFields == null){
			dataFields = processDefine.addNewDataFields();
		}
		result = dataFields.addNewDataField();
		return result;
	}
	
	public static InterceptorModel createInterceptorModel(ProcessDefine processDefine
			,String position,String activityId){
		Activities activities = processDefine.getActivities();

		ManualActivityType manualActivityType = getManualActivityType(activities, activityId);
		if (manualActivityType != null){
			if (BaseInterceptor.Position.in.equals(position)){
				if (manualActivityType.getInInterceptors() == null){
					return manualActivityType.addNewInInterceptors().addNewInterceptorModel();
				}else{
					return manualActivityType.getInInterceptors().addNewInterceptorModel();					
				}
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				if (manualActivityType.getOutInterceptors() == null){
					return manualActivityType.addNewOutInterceptors().addNewInterceptorModel();
				}else{
					return manualActivityType.getOutInterceptors().addNewInterceptorModel();	
				}
			}
		}
		
		AuditActivityType auditActivityType = getAuditActivityType(activities, activityId);
		if (auditActivityType != null){
			if (BaseInterceptor.Position.in.equals(position)){
				if (auditActivityType.getInInterceptors() == null){
					return auditActivityType.addNewInInterceptors().addNewInterceptorModel();
				}else{
					return auditActivityType.getInInterceptors().addNewInterceptorModel();					
				}
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				if (auditActivityType.getOutInterceptors() == null){
					return auditActivityType.addNewOutInterceptors().addNewInterceptorModel();
				}else{
					return auditActivityType.getOutInterceptors().addNewInterceptorModel();	
				}
			}
		}
		
		InvokeActivityType invokeActivityType = getInvokeActivityType(activities, activityId);
		if (invokeActivityType != null){
			if (BaseInterceptor.Position.in.equals(position)){
				if (invokeActivityType.getInInterceptors() == null){
					return invokeActivityType.addNewInInterceptors().addNewInterceptorModel();
				}else{
					return invokeActivityType.getInInterceptors().addNewInterceptorModel();					
				}
			}
			else if (BaseInterceptor.Position.out.equals(position)){
				//it's impossible !
			}
		}		
		return null;
	}
}
